"""
RedFire Framework - 服务基类

提供统一的服务基类，支持生命周期管理、依赖注入和配置管理。
"""

import logging
import asyncio
from abc import ABC, abstractmethod
from typing import Optional, Dict, Any, List
from contextlib import asynccontextmanager

from .registry import get_registry, ServiceRegistry
from .config import get_config_manager, ConfigManager
from .lifecycle import get_lifecycle_manager, ApplicationLifecycleManager

logger = logging.getLogger(__name__)


class ServiceBase(ABC):
    """
    服务基类
    
    提供通用的服务功能：
    - 生命周期管理（启动、停止、健康检查）
    - 依赖注入支持
    - 配置管理
    - 日志记录
    """

    def __init__(self, name: str = None, auto_register: bool = True):
        """
        初始化服务

        Args:
            name: 服务名称，默认使用类名
            auto_register: 是否自动注册到服务注册中心
        """
        self._name = name or self.__class__.__name__.lower()
        self._logger = logging.getLogger(f"{self.__module__}.{self.__class__.__name__}")
        self._config_manager: Optional[ConfigManager] = None
        self._registry: Optional[ServiceRegistry] = None
        self._lifecycle_manager: Optional[ApplicationLifecycleManager] = None
        self._is_started = False
        self._is_stopping = False
        self._dependencies: List[str] = []
        self._health_check_interval = 30  # seconds

        if auto_register:
            self._register_service()

    @property
    def name(self) -> str:
        """服务名称"""
        return self._name

    @property
    def logger(self) -> logging.Logger:
        """服务日志器"""
        return self._logger

    @property
    def is_started(self) -> bool:
        """是否已启动"""
        return self._is_started

    @property
    def is_stopping(self) -> bool:
        """是否正在停止"""
        return self._is_stopping

    def _register_service(self):
        """注册服务到注册中心"""
        try:
            registry = get_registry()
            registry.register_instance(self._name, self)
            self._registry = registry
            
            # 注册生命周期处理器
            lifecycle_manager = get_lifecycle_manager()
            lifecycle_manager.add_startup_handler(self._startup_wrapper)
            lifecycle_manager.add_shutdown_handler(self._shutdown_wrapper)
            self._lifecycle_manager = lifecycle_manager
            
            self._logger.debug(f"Service {self._name} registered successfully")
        except Exception as e:
            self._logger.error(f"Failed to register service {self._name}: {e}")
            raise

    async def _startup_wrapper(self):
        """启动包装器"""
        try:
            self._logger.info(f"Starting service: {self._name}")
            await self.startup()
            self._is_started = True
            self._logger.info(f"Service {self._name} started successfully")
        except Exception as e:
            self._logger.error(f"Failed to start service {self._name}: {e}")
            raise

    async def _shutdown_wrapper(self):
        """停止包装器"""
        if self._is_stopping:
            return
            
        try:
            self._is_stopping = True
            self._logger.info(f"Stopping service: {self._name}")
            await self.shutdown()
            self._is_started = False
            self._logger.info(f"Service {self._name} stopped successfully")
        except Exception as e:
            self._logger.error(f"Failed to stop service {self._name}: {e}")
            raise
        finally:
            self._is_stopping = False

    @abstractmethod
    async def startup(self):
        """
        服务启动逻辑
        
        子类必须实现此方法来定义服务启动时的行为
        """
        pass

    @abstractmethod
    async def shutdown(self):
        """
        服务停止逻辑
        
        子类必须实现此方法来定义服务停止时的清理行为
        """
        pass

    async def health_check(self) -> bool:
        """
        健康检查
        
        Returns:
            bool: 服务是否健康
        """
        return self._is_started and not self._is_stopping

    def get_config(self, key: str = None, default: Any = None) -> Any:
        """
        获取配置

        Args:
            key: 配置键，如果为None则返回整个配置
            default: 默认值

        Returns:
            配置值
        """
        if self._config_manager is None:
            self._config_manager = get_config_manager()

        if key is None:
            return self._config_manager.config
        
        return getattr(self._config_manager.config, key, default)

    def get_service(self, name: str) -> Any:
        """
        获取其他服务

        Args:
            name: 服务名称

        Returns:
            服务实例
        """
        if self._registry is None:
            self._registry = get_registry()
        
        return self._registry.get(name)

    def get_service_optional(self, name: str, default: Any = None) -> Any:
        """
        获取可选服务

        Args:
            name: 服务名称
            default: 默认值

        Returns:
            服务实例或默认值
        """
        if self._registry is None:
            self._registry = get_registry()
        
        return self._registry.get_optional(name, default)

    def add_dependency(self, service_name: str):
        """
        添加服务依赖

        Args:
            service_name: 依赖的服务名称
        """
        if service_name not in self._dependencies:
            self._dependencies.append(service_name)
            self._logger.debug(f"Added dependency: {service_name}")

    def get_dependencies(self) -> List[str]:
        """
        获取服务依赖列表

        Returns:
            依赖的服务名称列表
        """
        return self._dependencies.copy()

    async def wait_for_dependencies(self, timeout: float = 30.0):
        """
        等待依赖服务启动

        Args:
            timeout: 超时时间（秒）

        Raises:
            TimeoutError: 等待超时
        """
        if not self._dependencies:
            return

        async def check_dependencies():
            while True:
                all_ready = True
                for dep_name in self._dependencies:
                    try:
                        dep_service = self.get_service(dep_name)
                        if hasattr(dep_service, 'is_started') and not dep_service.is_started:
                            all_ready = False
                            break
                    except KeyError:
                        all_ready = False
                        break
                
                if all_ready:
                    break
                
                await asyncio.sleep(0.1)

        try:
            await asyncio.wait_for(check_dependencies(), timeout=timeout)
            self._logger.debug(f"All dependencies are ready for service: {self._name}")
        except asyncio.TimeoutError:
            self._logger.error(f"Timeout waiting for dependencies: {self._dependencies}")
            raise TimeoutError(f"Timeout waiting for dependencies: {self._dependencies}")

    @asynccontextmanager
    async def service_context(self):
        """
        服务上下文管理器
        
        自动处理服务的启动和停止
        """
        try:
            await self._startup_wrapper()
            yield self
        finally:
            await self._shutdown_wrapper()

    def __repr__(self) -> str:
        status = "started" if self._is_started else "stopped"
        return f"<{self.__class__.__name__}(name='{self._name}', status='{status}')>"


class AsyncServiceBase(ServiceBase):
    """
    异步服务基类
    
    专门为异步操作优化的服务基类
    """

    def __init__(self, name: str = None, auto_register: bool = True):
        super().__init__(name, auto_register)
        self._background_tasks: List[asyncio.Task] = []

    async def startup(self):
        """默认启动实现"""
        self._logger.debug(f"Async service {self._name} starting up")

    async def shutdown(self):
        """默认停止实现 - 取消所有后台任务"""
        self._logger.debug(f"Async service {self._name} shutting down")
        
        # 取消所有后台任务
        if self._background_tasks:
            self._logger.debug(f"Cancelling {len(self._background_tasks)} background tasks")
            for task in self._background_tasks:
                if not task.done():
                    task.cancel()
            
            # 等待任务完成
            await asyncio.gather(*self._background_tasks, return_exceptions=True)
            self._background_tasks.clear()

    def create_background_task(self, coro, name: str = None) -> asyncio.Task:
        """
        创建后台任务

        Args:
            coro: 协程对象
            name: 任务名称

        Returns:
            asyncio.Task: 创建的任务
        """
        task_name = name or f"{self._name}_background_task_{len(self._background_tasks)}"
        task = asyncio.create_task(coro, name=task_name)
        self._background_tasks.append(task)
        
        self._logger.debug(f"Created background task: {task_name}")
        return task

    async def health_check(self) -> bool:
        """
        异步服务健康检查
        
        检查服务状态和后台任务状态
        """
        if not await super().health_check():
            return False
        
        # 检查后台任务状态
        failed_tasks = [task for task in self._background_tasks if task.done() and task.exception()]
        if failed_tasks:
            self._logger.warning(f"Found {len(failed_tasks)} failed background tasks")
            return False
        
        return True


# 便利函数
def create_service(service_class, name: str = None, auto_register: bool = True, **kwargs):
    """
    创建服务实例

    Args:
        service_class: 服务类
        name: 服务名称
        auto_register: 是否自动注册
        **kwargs: 构造参数

    Returns:
        服务实例
    """
    return service_class(name=name, auto_register=auto_register, **kwargs)


async def start_all_services():
    """启动所有注册的服务"""
    lifecycle_manager = get_lifecycle_manager()
    await lifecycle_manager.startup()


async def stop_all_services():
    """停止所有注册的服务"""
    lifecycle_manager = get_lifecycle_manager()
    await lifecycle_manager.shutdown()


# 装饰器
def service_method(func):
    """服务方法装饰器 - 添加错误处理和日志"""
    async def wrapper(self, *args, **kwargs):
        method_name = func.__name__
        self._logger.debug(f"Calling service method: {method_name}")
        try:
            result = await func(self, *args, **kwargs)
            self._logger.debug(f"Service method {method_name} completed successfully")
            return result
        except Exception as e:
            self._logger.error(f"Service method {method_name} failed: {e}")
            raise
    return wrapper
